﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.DirectoryServices;
namespace Utility
{
    public class ADHelper
    {
        private string _path;
        private string _filterAttribute;

        public ADHelper()
        {
            var adserver = ConfigurationManager.AppSettings["ADServer"];
            _path = "LDAP://" + adserver;
        }
        public ADHelper(string path)
        {
            _path = path;
        }

        public bool IsAuthenticated(string domain, string username, string pwd)
        {
            string domainAndUsername = domain + @"\" + username;
            DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
            //do
            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();

                if (null == result)
                {
                    return false;
                }

                //Update the new path to the user in the directory.
                _path = result.Path;
                _filterAttribute = (string)result.Properties["cn"][0];
            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

            return true;
        }
        //public string GetUserEmail(string domain,  string username)
        //{
        //    string domainAndUsername = domain + @"\username"  ;
        //    DirectoryEntry entry = new DirectoryEntry(_path,domainAndUsername,"pass");
        //    //DirectoryEntry entry = new DirectoryEntry(_path);

        //    try
        //    {
        //        //Bind to the native AdsObject to force authentication.
        //        object obj = entry.NativeObject;

        //        DirectorySearcher search = new DirectorySearcher(entry);

        //        search.Filter = "(SAMAccountName=" + username + ")";
        //        //search.PropertiesToLoad.Add("cn");
        //        SearchResult result = search.FindOne();

        //        if (null == result)
        //        {
        //            return "none";
        //        }
        //        else
        //        {
        //            return (string)result.Properties["mail"][0];
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        throw new Exception("Error authenticating user. " + ex.Message);
        //        return ex.Message;
        //    }


        //}
        public string GetUserEmail(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                //search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                //DirectoryEntry result = entry.Find(username, "SAMAccountName");
                if (null == result)
                {
                    return "none";
                }
                else
                {
                    return (string)result.Properties["mail"][0];
                }

            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
                return ex.Message;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }

        public string GetDisplayName(string username)
        {

            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {
                //Bind to the native AdsObject to force authentication.
                //object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                //search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                //DirectoryEntry result = entry.Find(username, "SAMAccountName");
                if (null == result)
                {
                    return "none";
                }
                else
                {
                    return (string)result.Properties["displayName"][0];
                }

            }
            catch (Exception ex)
            {
                //  .HandleException(ex, "AD");
                throw;

            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }

        public string GetDepartment(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {
                //Bind to the native AdsObject to force authentication.
                //object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                //search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                //DirectoryEntry result = entry.Find(username, "SAMAccountName");
                if (null == result)
                {
                    return "none";
                }
                else
                {
                    return (string)result.Properties["Department"][0];
                }

            }
            catch (Exception ex)
            {
                //ExceptionPolicy.HandleException(ex, "AD");
                throw;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }
        /// <summary>
        /// get the boss's ID by user's ID
        /// </summary>
        /// <param name="department"></param>
        /// <returns></returns>
        public string GetSurpervisorID(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";

                SearchResult result = search.FindOne();

                if (null == result)
                {
                    return "none";
                }
                else
                {
                    string SurpervisorDisplayName;
                    //CN=Stanley LIU,OU=Users,OU=SHN,OU=China,OU=APAC,OU=Cognizant,DC=cts,DC=com
                    //Stanley LIU
                    SurpervisorDisplayName = (string)result.Properties["manager"][0].ToString().Split(',')[0].Substring(3);

                    DirectorySearcher searchID = new DirectorySearcher(entry);
                    searchID.Filter = search.Filter = "(name=" + SurpervisorDisplayName + ")";
                    //Stanley LIU
                    SearchResult resultID = searchID.FindOne();
                    if (null == resultID)
                    {
                        return "none";
                    }
                    else
                    {
                        //SAMAccountName ID
                        return (string)resultID.Properties["SAMAccountName"][0];
                    }

                }

            }
            catch (Exception ex)
            {
                //ExceptionPolicy.HandleException(ex, "AD");
                throw;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }
        /// <summary>
        /// get the boss's ID by user's Name
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public string GetSurpervisorName(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";

                SearchResult result = search.FindOne();

                if (null == result)
                {
                    return "none";
                }
                else
                {
                    //CN=Stanley LIU,OU=Users,OU=SHN,OU=China,OU=APAC,OU=Cognizant,DC=cts,DC=com
                    //Stanley LIU
                    return (string)result.Properties["manager"][0].ToString().Split(',')[0].Substring(3);

                }

            }
            catch (Exception ex)
            {
                //ExceptionPolicy.HandleException(ex, "AD");
                throw;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }

        public string GetSupervisor(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                //search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                //DirectoryEntry result = entry.Find(username, "SAMAccountName");
                if (null == result)
                {
                    return "none";
                }
                else
                {
                    //CN=Stanley LIU,OU=Users,OU=SHN,OU=China,OU=APAC,OU=Cognizant,DC=cts,DC=com
                    return (string)result.Properties["manager"][0];
                }

            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
                return ex.Message;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }

        public string GetJobTitle(string username)
        {


            DirectoryEntry entry = new DirectoryEntry(_path);

            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                //search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                //DirectoryEntry result = entry.Find(username, "SAMAccountName");
                if (null == result)
                {
                    return "none";
                }
                else
                {
                    return (string)result.Properties["title"][0];
                }

            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
                return ex.Message;
            }
            finally
            {
                entry.Close();
                entry.Dispose();
            }

        }


        public string GetGroups(string username)
        {
            DirectorySearcher search = new DirectorySearcher(_path);
            search.Filter = "(SAMAccountName=" + username + ")";
            search.PropertiesToLoad.Add("memberOf");
            StringBuilder groupNames = new StringBuilder();

            try
            {
                SearchResult result = search.FindOne();
                int propertyCount = result.Properties["memberOf"].Count;
                string dn;
                int equalsIndex, commaIndex;

                for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
                {
                    dn = (string)result.Properties["memberOf"][propertyCounter];
                    equalsIndex = dn.IndexOf("=", 1);
                    commaIndex = dn.IndexOf(",", 1);
                    if (-1 == equalsIndex)
                    {
                        return null;
                    }
                    groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
                    groupNames.Append("|");
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error obtaining group names. " + ex.Message);
            }
            return groupNames.ToString();
        }
    }
}
